/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package zombiedefense.framework;

import java.awt.Dimension;
import java.util.Iterator;
import zombiedefense.input.InputManager;
import zombiedefense.map.Spawner;
import zombiedefense.map.TileMap;
import zombiedefense.sprites.Zombie;
import zombiedefense.util.Timer;

/**
 * This object will handle the zombies in zombie defense,
 * including collision detection and wave advancement.
 * @author Connor Willison
 */
public class ZombieManager extends GameObjectManager{
    
    private int waveNumber = 0;
    private Timer waveTimer;	//holds time until next wave
    private static final long waveWait = 10000;	//secs between waves
    
    private EffectManager effects;
    
    private enum State{
	spawning,
	waiting_for_next_wave;
    };
    
    private State state;
    
    private Spawner spawner;
    private PlayerManager player;
    
    public ZombieManager(Dimension gameDims, TileMap map,InputManager input,EffectManager effects,PlayerManager player) {
	super(gameDims, map, input);
	
	waveTimer = new Timer(waveWait);
	spawner = new Spawner(this,map); //get spawnpoints from map
	
	this.effects = effects;
	this.player = player;
	
	state = State.waiting_for_next_wave;
	
    }
    
    public void update(long elapsedTime){
	
	//state machine - wave spawning system
	switch(state){
	    case spawning:
		//done the wave
		if(objects.isEmpty() && spawner.getRemainingToSpawn() <= 0){
		    //start waiting for next wave
		    state = State.waiting_for_next_wave;
		}else{
		    //keep spawning the wave
		    spawner.spawn(elapsedTime);
		}
		break;
	    
	    case waiting_for_next_wave:
		if(!waveTimer.isStarted()){
		    waveTimer.start();
		    waveTimer.reset();
		}
		
		waveTimer.update(elapsedTime);
		
		if(waveTimer.hasTicked()){
		    waveNumber++;
		    
		    //inform spawner that wave has advanced
		    spawner.waveHasChanged();
		    
		    //inform player that wave has advanced
		    player.getPlayer().notifyWaveAdvanced();
		    
		    //show text effect
		    //effects.addTextEffect("Wave" + waveNumber",x,y);
		    
		    //start spawning
		    state = State.spawning;
		    
		    //stop timer
		    waveTimer.stop();
		    waveTimer.reset();
		}
		
		break;
	}
	
	//perform zombie - player and zombie - barrier collision detection
	for(GameObject o: objects){
	    Zombie z = (Zombie)o;
	    z.checkIsPlayerInRange();
	    
	    //z.checkForBarriers(map);
	}
	
	super.update(elapsedTime);
	
    }
    
    public boolean isWaiting(){
	return state == State.waiting_for_next_wave;
    }
    
    public int getCurrentWave(){
	return waveNumber;
    }
    
    public long getTimeUntilNextWave(){
	return waveTimer.getTimeToNextTick();
    }
    
    public int getRemaining(){
	return objects.size();
    }
    
    public int getTotalForWave(){
	return spawner.getTotalForWave();
    }
    
    public Iterator getZombies(){
	return objects.iterator();
    }
}
